﻿using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CLFramework.Web.Utility
{
    /// <summary>
    /// 
    /// </summary>
    public static class ScriptUtility
    {
        #region Script Const

        private const string ScriptCloseWindow = "window.opener=null;window.close();";

        private const string ScriptCloseWindowFrame
            = "var oTarget = window.parent.parent.document.getElementById('WindowFrame');"
              + "window.parent.parent.document.body.removeChild(oTarget);";

        private const string ScriptHistoryBack = "window.history.back();return false;";

        /// <summary>
        /// javascript脚本前缀javascript:
        /// </summary>
        private const string scriptPrefix = "javascript:{0}";

        private const string ScriptRedirectOpener = "window.opener.location.href = '{0}';";
        private const string ScriptRedirectOpenerFrame = "window.parent.parent.location.href = '{0}';";

        private const string ScriptRefreshOpenerWindow = "window.opener.location.href = window.opener.location.href;";

        private const string ScriptRefreshOpenerWindowFrame =
            "window.parent.parent.location.href = window.parent.parent.location.href;";

        private const string ScriptReloadOpenerWindow = "window.opener.location.reload();";
        private const string ScriptReloadOpenerWindowFrame = "window.parent.parent.location.reload();";
        private const string ScriptReloadWindow = "window.location.reload();";

        /// <summary>
        /// javascript脚本标记&lt;script&gt;
        /// </summary>
        private const string scriptTag = "<script language='javascript'>{0}</script>";

        private const string ScriptWindowOpen = "window.open('{0}','_blank');";

        #endregion

        #region CloseWindowScript

        /// <summary>
        /// Gets the close window script.
        /// </summary>
        /// <value>The close window script.</value>
        public static string CloseWindowScript
        {
            get
            {
                switch (WebApplicationSettings.WindowStyle)
                {
                    case WindowStyle.Window:
                        return ScriptCloseWindow;
                    case WindowStyle.Frame:
                        return ScriptCloseWindowFrame;
                }
                return "";
            }
        }

        #endregion

        #region HistoryBackScript

        /// <summary>
        /// Gets the history back script.
        /// </summary>
        /// <value>The history back script.</value>
        public static string HistoryBackScript
        {
            get { return ScriptHistoryBack; }
        }

        #endregion

        #region RedirectOpenerScript

        /// <summary>
        /// Gets the redirect opener script.
        /// </summary>
        /// <value>The redirect opener script.</value>
        public static string RedirectOpenerScript
        {
            get
            {
                switch (WebApplicationSettings.WindowStyle)
                {
                    case WindowStyle.Window:
                        return ScriptRedirectOpener;
                    case WindowStyle.Frame:
                        return ScriptRedirectOpenerFrame;
                }
                return "";
            }
        }

        #endregion

        #region RefreshOpenerScript

        /// <summary>
        /// Gets the refresh opener script.
        /// </summary>
        /// <value>The refresh opener script.</value>
        public static string RefreshOpenerScript
        {
            get
            {
                switch (WebApplicationSettings.WindowStyle)
                {
                    case WindowStyle.Window:
                        return ScriptRefreshOpenerWindow;
                    case WindowStyle.Frame:
                        return ScriptRefreshOpenerWindowFrame;
                }
                return "";
            }
        }

        #endregion

        #region ReloadOpenerScript

        /// <summary>
        /// Gets the reload opener script.
        /// </summary>
        /// <value>The reload opener script.</value>
        public static string ReloadOpenerScript
        {
            get
            {
                switch (WebApplicationSettings.WindowStyle)
                {
                    case WindowStyle.Window:
                        return ScriptReloadOpenerWindow;
                    case WindowStyle.Frame:
                        return ScriptReloadOpenerWindowFrame;
                }
                return "";
            }
        }

        #endregion

        #region WindowOpenScript

        /// <summary>
        /// Gets the window open script.
        /// </summary>
        /// <value>The window open script.</value>
        public static string WindowOpenScript
        {
            get { return ScriptWindowOpen; }
        }

        #endregion

        #region ReloadWindowScript

        /// <summary>
        /// Gets the reload window script.
        /// </summary>
        /// <value>The reload window script.</value>
        public static string ReloadWindowScript
        {
            get { return ScriptReloadWindow; }
        }

        #endregion

        #region GetCloseWindowScript

        /// <summary>
        /// Gets the close window script.
        /// </summary>
        /// <returns></returns>
        public static string GetCloseWindowScript(bool addScriptPrefix)
        {
            switch (WebApplicationSettings.WindowStyle)
            {
                case WindowStyle.Window:
                    if (addScriptPrefix)
                    {
                        return AddScriptPrefix(ScriptCloseWindow);
                    }
                    return ScriptCloseWindow;
                case WindowStyle.Frame:
                    if (addScriptPrefix)
                    {
                        return AddScriptPrefix(ScriptCloseWindowFrame);
                    }
                    return ScriptCloseWindowFrame;
            }
            return "";
        }

        #endregion

        #region GetHistoryBackScript

        /// <summary>
        /// Gets the close window script.
        /// </summary>
        /// <returns></returns>
        public static string GetHistoryBackScript(bool addScriptPrefix)
        {
            if (addScriptPrefix)
            {
                return AddScriptPrefix(ScriptHistoryBack);
            }
            return ScriptHistoryBack;
        }

        #endregion

        #region AddScriptTag

        /// <summary>
        /// 给脚本加上&lt;script&gt;标记符号。
        /// </summary>
        /// <param name="script">需要加标记的脚本</param>
        /// <returns></returns>
        public static string AddScriptTag(string script)
        {
            return string.Format(scriptTag, script);
        }

        #endregion

        #region AddScriptPrefix

        /// <summary>
        /// 给脚本加上javascript:前缀。
        /// </summary>
        /// <param name="script">需要加前缀的脚本</param>
        /// <returns></returns>
        public static string AddScriptPrefix(string script)
        {
            return string.Format(scriptPrefix, script);
        }

        #endregion

        #region Open the window

        /// <summary>
        /// 在新窗口中打开网页
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="target">要打开的网页</param>
        public static void OpentWindow(Page page, string target)
        {
            string script = string.Format(ScriptWindowOpen, target);
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptOpenWindow", script, true);
        }

        #endregion

        #region CloseWindow

        /// <summary>
        /// Closes the window.
        /// </summary>
        /// <param name="page">The page.</param>
        public static void CloseWindow(Page page)
        {
            string script = GetCloseWindowScript(false);
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptCloseWindow", script, true);
        }

        #endregion

        #region RefreshWindow

        private const string scriptRefreshWindow = "window.location.href = window.location.href;";

        /// <summary>
        /// Refreshes the window.
        /// </summary>
        /// <param name="page">The page.</param>
        public static void RefreshWindow(Page page)
        {
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptRefreshWindow", scriptRefreshWindow, true);
        }

        #endregion

        #region RefreshOpener

        /// <summary>
        /// Refreshes the opener.
        /// </summary>
        /// <param name="page">The page.</param>
        public static void RefreshOpener(Page page)
        {
            string script = null;
            switch (WebApplicationSettings.WindowStyle)
            {
                case WindowStyle.Window:
                    script = ScriptRefreshOpenerWindow;
                    break;
                case WindowStyle.Frame:
                    script = ScriptReloadOpenerWindowFrame;
                    break;
            }
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptRefreshOpener",
                                                        script, true);
        }

        #endregion

        #region ReloadWindow

        /// <summary>
        /// Reload the window.
        /// </summary>
        /// <param name="page">The page.</param>
        public static void ReloadWindow(Page page)
        {
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptReloadWindow", ScriptReloadWindow, true);
        }

        #endregion

        #region ReloadOpener

        /// <summary>
        /// Reload the opener.
        /// </summary>
        /// <param name="page">The page.</param>
        public static void ReloadOpener(Page page)
        {
            string script = null;
            switch (WebApplicationSettings.WindowStyle)
            {
                case WindowStyle.Window:
                    script = ScriptReloadOpenerWindow;
                    break;
                case WindowStyle.Frame:
                    script = ScriptReloadOpenerWindowFrame;
                    break;
            }
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptReloadOpener",
                                                        script, true);
        }

        #endregion

        #region RedirectOpener

        /// <summary>
        /// 将父页面跳转到指定的URL.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="url">希望父页面跳转到的URL</param>
        public static void RedirectOpener(Page page, string url)
        {
            string script;
            switch (WebApplicationSettings.WindowStyle)
            {
                case WindowStyle.Window:
                    script = string.Format(ScriptRedirectOpener, url);
                    break;
                case WindowStyle.Frame:
                    script = string.Format(ScriptRedirectOpenerFrame, url);
                    break;
                default:
                    script = "";
                    break;
            }
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "scriptRedirectOpener",
                                                        script, true);
        }

        #endregion

        #region GotoPage

        /// <summary>
        /// 跳转到指定页面,自动添加a1,a2,a3参数
        /// </summary>
        /// <param name="url"></param>
        public static void GotoPage(string url)
        {
            if (HttpContext.Current.Request["a1"] != null)
            {
                string privateId = HttpContext.Current.Request["a1"];
                url += "&a1=" + privateId;
            }
            if (HttpContext.Current.Request["a2"] != null)
            {
                string privateId = HttpContext.Current.Request["a2"];
                url += "&a2=" + privateId;
            }
            if (HttpContext.Current.Request["a3"] != null)
            {
                string privateId = HttpContext.Current.Request["a3"];
                url += "&a3=" + privateId;
            }
            HttpContext.Current.Response.Redirect(url);
        }

        #endregion

        #region GetProgramParams

        /// <summary>
        /// 取得指定请求的所属程序参数，形如：prefix + "a1=123&#38;a2=1234&#38;a3=12345"
        /// </summary>
        /// <param name="Request">请求实例</param>
        /// <param name="prefix">结果前缀</param>
        /// <returns></returns>
        public static string GetProgramParams(HttpRequest Request, string prefix)
        {
            string url = string.Empty;
            if ((Request["a1"] != null) &&
                (Request["a2"] != null) &&
                (Request["a3"] != null))
            {
                url += prefix + "a1=" + Request["a1"];
                url += "&a2=" + Request["a2"];
                url += "&a3=" + Request["a3"];
            }
            return url;
        }

        /// <summary>
        /// 取得当前请求的所属程序参数，形如：prefix + "a1=123&#38;a2=1234&#38;a3=12345"
        /// </summary>
        /// <param name="prefix">结果前缀</param>
        /// <returns></returns>
        public static string GetProgramParams(string prefix)
        {
            return GetProgramParams(HttpContext.Current.Request, prefix);
        }

        /// <summary>
        /// 取得当前请求的所属程序参数，形如："a1=123&#38;a2=1234&#38;a3=12345"
        /// </summary>
        /// <returns></returns>
        public static string GetProgramParams()
        {
            return GetProgramParams(string.Empty);
        }

        #endregion

        #region SetMouseMove

        /// <summary>
        /// 设定鼠标移过时显示的内容
        /// </summary>
        /// <param name="control">要设定的控件</param>
        /// <param name="text">要显示的文本信息</param>
        public static void SetMouseMove(object control, string text)
        {
            if (control is IAttributeAccessor)
            {
                ((IAttributeAccessor)control).SetAttribute("onmouseover",
                                                            string.Format("window.status='{0}';return true;", text));

                ((IAttributeAccessor)control).SetAttribute("onmouseout",
                                                            "window.status='';return true;");
            }
        }

        #endregion

        #region Alert

        /// <summary>
        /// 显示警告对话框
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="message">要警告的文字</param>
        public static void Alert(Page page, string message)
        {
            string script = string.Format("javascript:alert('{0}');", message);
            ScriptManager.RegisterClientScriptBlock(page, page.GetType(), "scriptAlert", script, true);
        }

        #endregion

        #region FocusInputOnClickRadioButton

        /// <summary>
        /// 当选中RadioButton后将控件获得焦点。
        /// </summary>
        /// <param name="radioButton">RadioButton</param>
        /// <param name="inputControl">InputControl</param>
        /// <remarks>为了防止使用Response.Write方法重复定义脚本事件，
        /// 则使用此方法前要将以下脚本事件注册到页面中：<br/>
        /// &lt;!--<br/>
        ///function FocusInputOnClickRadioButton(radioButton, inputControl)<br/>
        ///{<br/>
        ///     if (radioButton.checked)<br/>
        ///     {<br/>
        ///         inputControl.focus();<br/>
        ///         if (inputControl.isTextEdit)<br/>
        ///         {<br/>
        ///             inputControl.select();<br/>
        ///         }<br/>
        ///     }<br/>
        ///}<br/>
        /// --&gt;<br/>
        /// </remarks>
        public static void FocusInputOnClickRadioButton(RadioButton radioButton, TextBox inputControl)
        {
            FocusInputOnClickRadioButton(radioButton, inputControl.ClientID);
        }

        /// <summary>
        /// 当选中RadioButton后将控件获得焦点。
        /// </summary>
        /// <param name="radioButton">RadioButton</param>
        /// <param name="inputControl">InputControl</param>
        /// <remarks>为了防止使用Response.Write方法重复定义脚本事件，
        /// 则使用此方法前要将以下脚本事件注册到页面中：<br/>
        /// &lt;!--<br/>
        ///function FocusInputOnClickRadioButton(radioButton, inputControl)<br/>
        ///{<br/>
        ///     if (radioButton.checked)<br/>
        ///     {<br/>
        ///         inputControl.focus();<br/>
        ///         if (inputControl.isTextEdit)<br/>
        ///         {<br/>
        ///             inputControl.select();<br/>
        ///         }<br/>
        ///     }<br/>
        ///}<br/>
        /// --&gt;<br/>
        /// </remarks>
        public static void FocusInputOnClickRadioButton(RadioButton radioButton, ListControl inputControl)
        {
            FocusInputOnClickRadioButton(radioButton, inputControl.ClientID);
        }

        /// <summary>
        /// 当选中RadioButton后将控件获得焦点。
        /// </summary>
        /// <param name="radioButton">RadioButton</param>
        /// <param name="inputControlID">InputControl ID</param>
        /// <remarks>为了防止使用Response.Write方法重复定义脚本事件，
        /// 则使用此方法前要将以下脚本事件注册到页面中：<br/>
        /// &lt;!--<br/>
        ///function FocusInputOnClickRadioButton(radioButton, inputControl)<br/>
        ///{<br/>
        ///     if (radioButton.checked)<br/>
        ///     {<br/>
        ///         inputControl.focus();<br/>
        ///         if (inputControl.isTextEdit)<br/>
        ///         {<br/>
        ///             inputControl.select();<br/>
        ///         }<br/>
        ///     }<br/>
        ///}<br/>
        /// --&gt;<br/>
        /// </remarks>
        public static void FocusInputOnClickRadioButton(RadioButton radioButton, string inputControlID)
        {
            const string script = "javascript:FocusInputOnClickRadioButton({0},{1})";
            radioButton.Attributes["onclick"] = string.Format(script, radioButton.ClientID, inputControlID);
        }

        #endregion

        #region FocusInputOnClickCheckBox

        /// <summary>
        /// 当选中CheckBox后将控件获得焦点。
        /// </summary>
        /// <param name="checkBox">CheckBox</param>
        /// <param name="inputControl">要获得焦点的控件</param>
        public static void FocusInputOnClickCheckBox(CheckBox checkBox, WebControl inputControl)
        {
            const string script = "javascript:FocusInputOnClickRadioButton({0},{1})";
            checkBox.Attributes["onclick"] = string.Format(script, checkBox.ClientID, inputControl.ClientID);
        }

        #endregion

        #region CheckRadioButtonOnInputFucus

        /// <summary>
        /// 当控件获得焦点后将选中RadioButton。
        /// </summary>
        /// <param name="radioButton">RadioButton</param>
        /// <param name="inputControl">InputControl</param>
        /// <remarks>为了防止使用Response.Write方法重复定义脚本事件，
        /// 则使用此方法前要将以下脚本事件注册到页面中：<br/>
        /// <!--
        ///function CheckRadioButtonOnInputFucus(radioButton)
        ///{
        ///    radioButton.checked = true;
        ///}
        /// -->
        /// </remarks>
        public static void CheckRadioButtonOnInputFucus(RadioButton radioButton, object inputControl)
        {
            if (inputControl is IAttributeAccessor)
            {
                const string script = "javascript:CheckRadioButtonOnInputFucus({0})";
                ((IAttributeAccessor)inputControl).SetAttribute("onfocus",
                                                                 string.Format(script, radioButton.ClientID));
            }
        }

        #endregion

        #region SelectCheckBoxOnInputFucus

        /// <summary>
        /// 当控件获得焦点后将选中CheckBox。
        /// </summary>
        /// <param name="checkBox">CheckBox</param>
        /// <param name="inputControl">InputControl</param>
        public static void SelectCheckBoxOnInputFucus(CheckBox checkBox, object inputControl)
        {
            if (inputControl is IAttributeAccessor)
            {
                const string script = "javascript:CheckRadioButtonOnInputFucus({0})";
                ((IAttributeAccessor)inputControl).SetAttribute("onfocus",
                                                                 string.Format(script, checkBox.ClientID));
            }
        }

        #endregion

        #region RemoveQueryParamsFromUrl

        /// <summary>
        /// 从url中移除指定的参数
        /// </summary>
        /// <param name="url">原url</param>
        /// <param name="name">要移除的参数名称</param>
        /// <returns>移除后的url</returns>
        public static string RemoveQueryParamsFromUrl(string url, string name)
        {
            string result = Regex.Replace(url, "(\\?)(" + name + "=[^&$]*)", "$1", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "&" + name + "=[^&$]*", string.Empty, RegexOptions.IgnoreCase);

            return result;
        }

        #endregion
    }
}
